
package search.fitnessfunctions;
import java.util.ArrayList;
import java.util.List;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import static org.junit.Assert.*;
import primitives.cluster.ClusterHead;
import primitives.cluster.ClusterNode;
import primitives.cluster.ClusterUtils;
import primitives.graph.Graph;
import primitives.graph.Node;

/**
 *
 * @author mat
 */
public class LutzFFTest {
    
    ClusterHead goodTree, badTree;

    
    TreeFitnessFunction groovyVersion, javaVersion;
    
    public LutzFFTest() {
    }
    
	Graph g;
	List<Node> nodes;
    @Before
    public void setUp() {
        g = new Graph();
		//make a strongly connected graph
		
		nodes = new ArrayList<Node>();
		
		
        nodes.add(new Node("node 1"));
        nodes.add(new Node("node 2"));
        nodes.add(new Node("node 3"));
		
		nodes.add(new Node("node 4"));
		
		
        for(Node n :nodes){
            g.addNode(n);
        }
        nodes.get(0).connect(nodes.get(1), "gol");
		nodes.get(1).connect(nodes.get(2), "lel");
		nodes.get(0).connect(nodes.get(2), "ho");
		nodes.get(1).connect(nodes.get(3), "hi");

		
		
        groovyVersion = new search.fitnessfunctions.LutzHMDFF();
        
        
        
		javaVersion = new search.fitnessfunctions.LutzFitnessFunction();
		

    }
    
    @After
    public void tearDown() {
    }

	
	@Test
	public void testOneSmallerComponentOneTreeLevel(){
		goodTree = new ClusterHead();
        
        ClusterNode mainThree = new ClusterNode();
		mainThree.addNode(nodes.get(0));
		mainThree.addNode(nodes.get(1));
		mainThree.addNode(nodes.get(2));
		
		ClusterNode separate = new ClusterNode();
		separate.addNode(nodes.get(3));
		
		goodTree.addChild(mainThree);
		goodTree.addChild(separate);
		groovyVersion.setTree(goodTree);
        javaVersion.setTree(goodTree);
		
		testAreSame();
	}
	
		@Test
	public void testTwoOneElementClustersOneLevel(){
		goodTree = new ClusterHead();
        
        ClusterNode c1 = new ClusterNode();
		c1.addNode(nodes.get(0));
		c1.addNode(nodes.get(1));
		
		ClusterNode c2 = new ClusterNode();
		c2.addNode(nodes.get(2));
		
		ClusterNode separate = new ClusterNode();
		separate.addNode(nodes.get(3));
		
		goodTree.addChild(c1);
		goodTree.addChild(c2);
		goodTree.addChild(separate);
		groovyVersion.setTree(goodTree);
        javaVersion.setTree(goodTree);
		
		testAreSame();
	}
	
	@Test
	public void testTwoLevelClustersUnbalanced(){
		goodTree = new ClusterHead();
        
        ClusterNode c1 = new ClusterNode();
		c1.addNode(nodes.get(0));
		c1.addNode(nodes.get(1));
		
		ClusterNode c2 = new ClusterNode();
		c2.addNode(nodes.get(2));
		
		ClusterNode parentOfC1And2 = new ClusterNode();
		parentOfC1And2.addChild(c2);
		parentOfC1And2.addChild(c1);
		
		
		ClusterNode separate = new ClusterNode();
		separate.addNode(nodes.get(3));
		
		goodTree.addChild(parentOfC1And2);
		goodTree.addChild(separate);
		groovyVersion.setTree(goodTree);
        javaVersion.setTree(goodTree);
		
		testAreSame();
	}
	
		@Test
	public void twoLevelBalancedClusters(){
		goodTree = new ClusterHead();
        
        ClusterNode c1 = new ClusterNode();
		c1.addNode(nodes.get(0));
		c1.addNode(nodes.get(1));
		
		ClusterNode c2 = new ClusterNode();
		c2.addNode(nodes.get(2));
		
		ClusterNode parentOfC1And2 = new ClusterNode();
		parentOfC1And2.addChild(c2);
		parentOfC1And2.addChild(c1);
		
		
		ClusterNode separate = new ClusterNode();
		separate.addNode(nodes.get(3));
		
		goodTree.addChild(parentOfC1And2);
		
		ClusterNode parentOfSeparate = new ClusterNode();
		parentOfSeparate.addChild(separate);
		
		goodTree.addChild(parentOfSeparate);
		groovyVersion.setTree(goodTree);
        javaVersion.setTree(goodTree);
		
		testAreSame();
	}
	
		
    /**
     * Test of setTree method, of class BunchTurboMQFitnessFunction.
     */
    public void testAreSame() {
        assertNotSame(Double.NaN, groovyVersion.evaluate(goodTree));
		
        assertNotSame(Double.NaN, javaVersion.evaluate(goodTree));
		assertEquals(javaVersion.evaluate(goodTree), groovyVersion.evaluate(goodTree), 0.0001);
    }

}
